/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#version 460  core

; // preprocessor add semicolon to isolate error messages
#line 1 1 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScaling_vs.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef POWERSCALING_VS_H_HGLSL
#define POWERSCALING_VS_H_HGLSL

uniform vec4 campos;
uniform mat4 camrot;
uniform vec2 scaling;
uniform vec4 objpos;

; // preprocessor add semicolon to isolate error messages
#line 1 2 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScalingMath.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef POWERSCALING_MATH_HGLSL
#define POWERSCALING_MATH_HGLSL


const float k = 10.0;
const float FLT_MAX = 1e38; // Not max but large enough for the purpose

float log10(float x) {
    return log(x) / log(10.0);
}

vec4 psc_normalization(vec4 v) {
    vec4 v2 = v;
    float l = length(v.xyz);
    v2.xyz = v.xyz / l;
    v2.w = v.w - log10(1.0/l);
    return v2;
}

vec4 psc_addition(vec4 v1, vec4 v2) {
    float ds = v2.w - v1.w;
    if(ds >= 0) {
        float p = pow(k,-ds);
        return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w);
    } else {
        float p = pow(k,ds);
        return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w);
    }
}

vec4 psc_subtraction(vec4 v1, vec4 v2) {
    vec4 negV2 = vec4(-v2.xyz, v2.w);
    return psc_addition(v1, negV2);
}

vec2 psc_addition(vec2 v1, vec2 v2) {
    float ds = v2.y - v1.y;
    if(ds >= 0) {
        float p = pow(k,-ds);
        return vec2(v1.x*p + v2.x, v2.y);
    } else {
        float p = pow(k,ds);
        return vec2(v1.x + v2.x*p, v1.y);
    }
}

vec2 psc_subtraction(vec2 v1, vec2 v2) {
    vec2 negV2 = vec2(-v2.x, v2.y);
    return psc_addition(v1, negV2);
}


vec4 z_normalization(vec4 v_in) {
    vec4 v_out = v_in;
    v_out.z = 0;
    //if ( v_out.z < -v_out.w )
    //  v_out.z = -v_out.w;
    //else if (v_out.z > v_out.w)
    //  v_out.z = v_out.w;
    return v_out;
}

/**
 * Convert a psc vector to a float
 */
vec3 pscToLinear(vec4 position) {
    return pow(k, position.w) * position.xyz;
}

/**
 * Convert a psc scalar to a float
 */
float pscToLinear(vec2 position) {
    return pow(k, position.y) * position.x;
}

#endif
; // preprocessor add semicolon to isolate error messages
#line 34 1 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScaling_vs.hglsl

vec4 psc_to_meter(vec4 v1, vec2 v2) {
    float factor = v2.x * pow(k,v2.y + v1.w);
    return vec4(v1.xyz * factor, 1.0);
}

vec4 psc_scaling(vec4 v1, vec2 v2) {
    float ds = v2.y - v1.w;
    if(ds >= 0) {
        return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y);
    } else {
        return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w);
    }
}

// vertexPosition is returned as the transformed vertex in OS Camera Rig Space in PSC
vec4 pscTransform(inout vec4 vertexPosition, mat4 modelTransform) {
    vec3 local_vertex_pos = mat3(modelTransform) * vertexPosition.xyz;
    
    // PSC addition; local vertex position and the object power scaled world position
    vertexPosition = psc_addition(vec4(local_vertex_pos,vertexPosition.w),objpos);
    
    // PSC addition; rotated and viewscaled vertex and the cameras negative position
    vertexPosition = psc_addition(vertexPosition,vec4(-campos.xyz,campos.w));
    
    // rotate the camera
    vertexPosition.xyz =  mat3(camrot) * vertexPosition.xyz;
    vec4 tmp = vertexPosition;
    vertexPosition = psc_scaling(vertexPosition, scaling);
    
    // project using the rescaled coordinates,
    tmp = psc_to_meter(tmp, scaling);
    
    // Return the vertex tranformed to OS Camera Rig Space
    // in meters.
    return tmp;
}

#endif
; // preprocessor add semicolon to isolate error messages
#line 28 0 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\localrenderer_vs.glsl
; // preprocessor add semicolon to isolate error messages
#line 1 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tile.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef TEXTURETILE_HGLSL
#define TEXTURETILE_HGLSL

struct TileDepthTransform {
    float depthScale;
    float depthOffset;
};

struct TileUvTransform {
    vec2 uvOffset;
    vec2 uvScale;
};

struct ChunkTile {
    sampler2D textureSampler;
    TileUvTransform uvTransform;
};

struct PixelPadding {
    ivec2 startOffset;
    ivec2 sizeDifference;
};

struct ChunkTilePile {
    ChunkTile chunkTile0;
    ChunkTile chunkTile1;
    ChunkTile chunkTile2;
};

struct LayerSettings {
    float opacity;
    float gamma;
    float multiplier;
    float offset;
    float valueBlending;
};

struct LayerAdjustment {
    vec3 chromaKeyColor;
    float chromaKeyTolerance;
};

struct Layer {
    ChunkTilePile pile;
    TileDepthTransform depthTransform;
    LayerSettings settings;
    LayerAdjustment adjustment;
    PixelPadding padding;
    
    // Other layer type properties stuff
    vec3 color;
};

#endif // TEXTURETILE_HGLSL
; // preprocessor add semicolon to isolate error messages
#line 29 0 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\localrenderer_vs.glsl
; // preprocessor add semicolon to isolate error messages
#line 1 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef TEXTURETILEMAPPING_HGLSL
#define TEXTURETILEMAPPING_HGLSL

; // preprocessor add semicolon to isolate error messages
#line 1 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tile.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef TEXTURETILE_HGLSL
#define TEXTURETILE_HGLSL

struct TileDepthTransform {
    float depthScale;
    float depthOffset;
};

struct TileUvTransform {
    vec2 uvOffset;
    vec2 uvScale;
};

struct ChunkTile {
    sampler2D textureSampler;
    TileUvTransform uvTransform;
};

struct PixelPadding {
    ivec2 startOffset;
    ivec2 sizeDifference;
};

struct ChunkTilePile {
    ChunkTile chunkTile0;
    ChunkTile chunkTile1;
    ChunkTile chunkTile2;
};

struct LayerSettings {
    float opacity;
    float gamma;
    float multiplier;
    float offset;
    float valueBlending;
};

struct LayerAdjustment {
    vec3 chromaKeyColor;
    float chromaKeyTolerance;
};

struct Layer {
    ChunkTilePile pile;
    TileDepthTransform depthTransform;
    LayerSettings settings;
    LayerAdjustment adjustment;
    PixelPadding padding;
    
    // Other layer type properties stuff
    vec3 color;
};

#endif // TEXTURETILE_HGLSL
; // preprocessor add semicolon to isolate error messages
#line 29 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
; // preprocessor add semicolon to isolate error messages
#line 1 5 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\blending.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef BLENDING_HGLSL
#define BLENDING_HGLSL

vec4 blendNormal(vec4 oldColor, vec4 newColor) {
    vec4 toReturn;
    toReturn.a = mix(oldColor.a, 1.0, newColor.a);
    toReturn.rgb =
        (newColor.rgb * newColor.a + oldColor.rgb * oldColor.a * (1 - newColor.a)) /
        toReturn.a;
    return toReturn;
}

vec4 blendMultiply(vec4 oldColor, vec4 newColor) {
    return oldColor * newColor;
}

vec4 blendAdd(vec4 oldColor, vec4 newColor) {
    return oldColor + newColor;
}

vec4 blendSubtract(vec4 oldColor, vec4 newColor) {
    return oldColor - newColor;
}

vec3 hsl2rgb(in vec3 c) {
    vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);

    return c.z + c.y * (rgb - 0.5) * (1.0 - abs(2.0 * c.z - 1.0));
}

vec3 HueShift(in vec3 color, in float shift) {
    vec3 P = vec3(0.55735) * dot(vec3(0.55735), color);
    vec3 U = color - P;
    vec3 V = cross(vec3(0.55735), U);
    vec3 c = U * cos(shift*6.2832) + V * sin(shift*6.2832) + P;
    return c;
}

vec3 rgb2hsl(in vec3 c) {
    float r = c.r;
    float g = c.g;
    float b = c.b;
    float cMin = min(r, min(g, b));
    float cMax = max(r, max(g, b));

    if (cMax > cMin) {
        float l = (cMax + cMin) / 2.0;

        float cDelta = cMax - cMin;

        //s = l < .05 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) ); Original
        float s = (l < 0.0) ? cDelta / (cMax + cMin) : cDelta / (2.0 - (cMax + cMin));

        float h = 0.0;
         if (r == cMax) {
            h = (g - b) / cDelta;
        }
        else if (g == cMax) {
            h = 2.0 + (b - r) / cDelta;
        }
        else {
            h = 4.0 + (r - g) / cDelta;
        }

        if (h < 0.0) {
            h += 6.0;
        }
        h = h / 6.0;

        return vec3(h, s, l);
    }
    else {
        return vec3(0.0);
    }
}

vec3 rgb2hsv(vec3 c) {
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = (c.g < c.b) ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
    vec4 q = (c.r < p.x) ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);

    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

vec3 hsv2rgb(vec3 c) {
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

#endif
; // preprocessor add semicolon to isolate error messages
#line 30 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

// First layer type from LayerShaderManager is height map
#define NUMLAYERS_HEIGHTMAP 0 + 1
#define USE_HEIGHTMAP 0
#define HEIGHTMAP_BLENDING_ENABLED 1

// Second layer type from LayerShaderManager is color texture
#define NUMLAYERS_COLORTEXTURE 0 + 1
#define USE_COLORTEXTURE 0
#define COLORTEXTURE_BLENDING_ENABLED 1

 // Third layer type from LayerShaderManager is water mask
#define NUMLAYERS_WATERMASK 0 + 1
#define USE_WATERMASK 0
#define WATERMASK_BLENDING_ENABLED 1

// Fourth layer type from LayerShaderManager is night texture
#define NUMLAYERS_NIGHTTEXTURE 0 + 1
#define USE_NIGHTTEXTURE 0
#define NIGHTTEXTURE_BLENDING_ENABLED 1

// Fifth layer type from LayerShaderManager is overlay
#define NUMLAYERS_OVERLAY 0 + 1
#define USE_OVERLAY 0
#define OVERLAY_BLENDING_ENABLED 1

// Global constants
#define CHUNK_DEFAULT_HEIGHT 0.000000

// Other key value pairs used for settings
#define USE_ACCURATE_NORMALS 0
#define PERFORM_SHADING 1
#define USE_ECLIPSE_SHADOWS 0
#define USE_ECLIPSE_HARD_SHADOWS 0
#define SHOW_CHUNK_EDGES 0
#define SHOW_HEIGHT_RESOLUTION 0
#define SHOW_HEIGHT_INTENSITIES 0
#define SHADOW_MAPPING_ENABLED 0

const vec3 DefaultLevelWeights = vec3(1.0, 0.0, 0.0);

float orenNayarDiffuse(vec3 lightDirection, vec3 viewDirection, vec3 surfaceNormal,
                       float roughness)
{
    // calculate intermediary values
    float NdotL = dot(surfaceNormal, lightDirection);
    float NdotV = dot(surfaceNormal, viewDirection);

    float angleVN = acos(NdotV);
    float angleLN = acos(NdotL);
    
    float alpha = max(angleVN, angleLN);
    float beta = min(angleVN, angleLN);
    float gamma = dot(
        viewDirection - surfaceNormal * dot(viewDirection, surfaceNormal),
        lightDirection - surfaceNormal * dot(lightDirection, surfaceNormal)
    );
    
    float roughnessSquared = roughness * roughness;
    
    // calculate A and B
    float A = 1.0 - 0.5 * (roughnessSquared / (roughnessSquared + 0.57));
    float B = 0.45 * (roughnessSquared / (roughnessSquared + 0.09));
    float C = sin(alpha) * tan(beta);
    
    // put it all together
    return max(0.0, NdotL) * (A + B * max(0.0, gamma) * C);
}

float performLayerSettings(float currentValue, LayerSettings settings) {
    float v = sign(currentValue) * pow(abs(currentValue), settings.gamma) *
              settings.multiplier + settings.offset;
    return v * settings.opacity;
}

vec4 performLayerSettings(vec4 currentValue, LayerSettings settings) {
    vec3 newValue = sign(currentValue.rgb) * pow(abs(currentValue.rgb), vec3(settings.gamma)) *
           settings.multiplier + settings.offset;
    return vec4(newValue, currentValue.a * settings.opacity);
}

vec2 tileUVToTextureSamplePosition(ChunkTile chunkTile, vec2 tileUV,
                                   PixelPadding padding)
{
    vec2 uv = chunkTile.uvTransform.uvOffset + chunkTile.uvTransform.uvScale * tileUV;

    // compensateSourceTextureSampling
    ivec2 resolution = textureSize(chunkTile.textureSampler, 0);
    vec2 sourceSize = vec2(resolution) + padding.sizeDifference;
    vec2 currentSize = vec2(resolution);
    vec2 sourceToCurrentSize = currentSize / sourceSize;
    return sourceToCurrentSize * (uv - padding.startOffset / sourceSize);
}

vec4 getTexVal(ChunkTilePile chunkTilePile, vec3 w, vec2 uv,
               PixelPadding padding)
{
    vec4 v1 = texture(
        chunkTilePile.chunkTile0.textureSampler,
        tileUVToTextureSamplePosition(chunkTilePile.chunkTile0, uv, padding)
    );
    vec4 v2 = texture(
        chunkTilePile.chunkTile1.textureSampler,
        tileUVToTextureSamplePosition(chunkTilePile.chunkTile1, uv, padding)
    );
    vec4 v3 = texture(
        chunkTilePile.chunkTile2.textureSampler,
        tileUVToTextureSamplePosition(chunkTilePile.chunkTile2, uv, padding)
    );

    return w.x * v1 + w.y * v2 + w.z * v3;
}

//# For loop over layerGroups
//# Key 0 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 144 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 145 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 getSampleHeightLayers0(vec2 uv, vec3 levelWeights,
                            Layer HeightLayers[0 + 1])
{
    vec4 color = vec4(0.0, 0.0, 0.0, 1.0);

    // All tile layers are the same. Sample from texture
#if (0 == 0) // DefaultTileLayer
    color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
#elif (0 == 1) // SingleImageTileLayer
    color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
#elif (0 == 2) // SizeReferenceTileLayer
    color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
#elif (0 == 3) // TemporalTileLayer
    color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
#elif (0 == 4) // TileIndexTileLayer
    color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
#elif (0 == 5) // ByIndexTileLayer
    color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
#elif (0 == 6) // ByLevelTileLayer
    color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
#elif (0 == 7) // SolidColor
    color.rgb = HeightLayers[0].color;
#endif

    return color;
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 174 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 1 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 175 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 145 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 getSampleColorLayers0(vec2 uv, vec3 levelWeights,
                            Layer ColorLayers[0 + 1])
{
    vec4 color = vec4(0.0, 0.0, 0.0, 1.0);

    // All tile layers are the same. Sample from texture
#if (0 == 0) // DefaultTileLayer
    color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
#elif (0 == 1) // SingleImageTileLayer
    color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
#elif (0 == 2) // SizeReferenceTileLayer
    color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
#elif (0 == 3) // TemporalTileLayer
    color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
#elif (0 == 4) // TileIndexTileLayer
    color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
#elif (0 == 5) // ByIndexTileLayer
    color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
#elif (0 == 6) // ByLevelTileLayer
    color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
#elif (0 == 7) // SolidColor
    color.rgb = ColorLayers[0].color;
#endif

    return color;
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 174 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 2 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 175 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 145 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 getSampleOverlays0(vec2 uv, vec3 levelWeights,
                            Layer Overlays[0 + 1])
{
    vec4 color = vec4(0.0, 0.0, 0.0, 1.0);

    // All tile layers are the same. Sample from texture
#if (0 == 0) // DefaultTileLayer
    color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
#elif (0 == 1) // SingleImageTileLayer
    color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
#elif (0 == 2) // SizeReferenceTileLayer
    color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
#elif (0 == 3) // TemporalTileLayer
    color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
#elif (0 == 4) // TileIndexTileLayer
    color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
#elif (0 == 5) // ByIndexTileLayer
    color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
#elif (0 == 6) // ByLevelTileLayer
    color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
#elif (0 == 7) // SolidColor
    color.rgb = Overlays[0].color;
#endif

    return color;
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 174 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 3 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 175 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 145 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 getSampleNightLayers0(vec2 uv, vec3 levelWeights,
                            Layer NightLayers[0 + 1])
{
    vec4 color = vec4(0.0, 0.0, 0.0, 1.0);

    // All tile layers are the same. Sample from texture
#if (0 == 0) // DefaultTileLayer
    color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
#elif (0 == 1) // SingleImageTileLayer
    color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
#elif (0 == 2) // SizeReferenceTileLayer
    color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
#elif (0 == 3) // TemporalTileLayer
    color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
#elif (0 == 4) // TileIndexTileLayer
    color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
#elif (0 == 5) // ByIndexTileLayer
    color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
#elif (0 == 6) // ByLevelTileLayer
    color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
#elif (0 == 7) // SolidColor
    color.rgb = NightLayers[0].color;
#endif

    return color;
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 174 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 4 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 175 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 145 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 getSampleWaterMasks0(vec2 uv, vec3 levelWeights,
                            Layer WaterMasks[0 + 1])
{
    vec4 color = vec4(0.0, 0.0, 0.0, 1.0);

    // All tile layers are the same. Sample from texture
#if (0 == 0) // DefaultTileLayer
    color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
#elif (0 == 1) // SingleImageTileLayer
    color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
#elif (0 == 2) // SizeReferenceTileLayer
    color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
#elif (0 == 3) // TemporalTileLayer
    color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
#elif (0 == 4) // TileIndexTileLayer
    color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
#elif (0 == 5) // ByIndexTileLayer
    color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
#elif (0 == 6) // ByLevelTileLayer
    color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
#elif (0 == 7) // SolidColor
    color.rgb = WaterMasks[0].color;
#endif

    return color;
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 174 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Terminated loop over layerGroups
; // preprocessor add semicolon to isolate error messages
#line 175 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

//# For loop over layerGroups
//# Key 0 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 177 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 178 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 blendHeightLayers0(vec4 currentColor, vec4 newColor, float blendFactor) {
#if (0 == 0) // Default, Normal
    return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
#elif (0 == 1) // Multiply
    return blendMultiply(currentColor, newColor * blendFactor);
#elif (0 == 2) // Add
    return blendAdd(currentColor, newColor * blendFactor);
#elif (0 == 3) // Subtract
    return blendSubtract(currentColor, newColor * blendFactor);
#elif (0 == 4) // Color
    // Convert color to grayscale
    float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
    
    vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
    // Use gray from new color as value in hsv
    vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
    vec3 rgbNew = hsv2rgb(hsvNew);

    vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
    return color;
#endif
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 203 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 1 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 204 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 178 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 blendColorLayers0(vec4 currentColor, vec4 newColor, float blendFactor) {
#if (0 == 0) // Default, Normal
    return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
#elif (0 == 1) // Multiply
    return blendMultiply(currentColor, newColor * blendFactor);
#elif (0 == 2) // Add
    return blendAdd(currentColor, newColor * blendFactor);
#elif (0 == 3) // Subtract
    return blendSubtract(currentColor, newColor * blendFactor);
#elif (0 == 4) // Color
    // Convert color to grayscale
    float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
    
    vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
    // Use gray from new color as value in hsv
    vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
    vec3 rgbNew = hsv2rgb(hsvNew);

    vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
    return color;
#endif
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 203 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 2 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 204 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 178 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 blendOverlays0(vec4 currentColor, vec4 newColor, float blendFactor) {
#if (0 == 0) // Default, Normal
    return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
#elif (0 == 1) // Multiply
    return blendMultiply(currentColor, newColor * blendFactor);
#elif (0 == 2) // Add
    return blendAdd(currentColor, newColor * blendFactor);
#elif (0 == 3) // Subtract
    return blendSubtract(currentColor, newColor * blendFactor);
#elif (0 == 4) // Color
    // Convert color to grayscale
    float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
    
    vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
    // Use gray from new color as value in hsv
    vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
    vec3 rgbNew = hsv2rgb(hsvNew);

    vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
    return color;
#endif
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 203 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 3 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 204 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 178 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 blendNightLayers0(vec4 currentColor, vec4 newColor, float blendFactor) {
#if (0 == 0) // Default, Normal
    return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
#elif (0 == 1) // Multiply
    return blendMultiply(currentColor, newColor * blendFactor);
#elif (0 == 2) // Add
    return blendAdd(currentColor, newColor * blendFactor);
#elif (0 == 3) // Subtract
    return blendSubtract(currentColor, newColor * blendFactor);
#elif (0 == 4) // Color
    // Convert color to grayscale
    float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
    
    vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
    // Use gray from new color as value in hsv
    vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
    vec3 rgbNew = hsv2rgb(hsvNew);

    vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
    return color;
#endif
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 203 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 4 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 204 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 178 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 blendWaterMasks0(vec4 currentColor, vec4 newColor, float blendFactor) {
#if (0 == 0) // Default, Normal
    return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
#elif (0 == 1) // Multiply
    return blendMultiply(currentColor, newColor * blendFactor);
#elif (0 == 2) // Add
    return blendAdd(currentColor, newColor * blendFactor);
#elif (0 == 3) // Subtract
    return blendSubtract(currentColor, newColor * blendFactor);
#elif (0 == 4) // Color
    // Convert color to grayscale
    float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
    
    vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
    // Use gray from new color as value in hsv
    vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
    vec3 rgbNew = hsv2rgb(hsvNew);

    vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
    return color;
#endif
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 203 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Terminated loop over layerGroups
; // preprocessor add semicolon to isolate error messages
#line 204 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl


//# For loop over layerGroups
//# Key 0 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 207 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 208 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 performAdjustmentHeightLayers0(vec4 currentColor,
                                        LayerAdjustment adjustment)
{
#if (0 == 0) // Default, None
    return currentColor;
#elif (0 == 1) // ChromaKey
    if (distance(
        currentColor.rgb,
        adjustment.chromaKeyColor
        ) <= adjustment.chromaKeyTolerance)
    {
        return vec4(0.0);
    }
    else {
        return currentColor;
    }
#elif (0 == 2) // TransferFunction
    return currentColor;
#else
    return currentColor;
#endif
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 233 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 1 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 234 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 208 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 performAdjustmentColorLayers0(vec4 currentColor,
                                        LayerAdjustment adjustment)
{
#if (0 == 0) // Default, None
    return currentColor;
#elif (0 == 1) // ChromaKey
    if (distance(
        currentColor.rgb,
        adjustment.chromaKeyColor
        ) <= adjustment.chromaKeyTolerance)
    {
        return vec4(0.0);
    }
    else {
        return currentColor;
    }
#elif (0 == 2) // TransferFunction
    return currentColor;
#else
    return currentColor;
#endif
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 233 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 2 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 234 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 208 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 performAdjustmentOverlays0(vec4 currentColor,
                                        LayerAdjustment adjustment)
{
#if (0 == 0) // Default, None
    return currentColor;
#elif (0 == 1) // ChromaKey
    if (distance(
        currentColor.rgb,
        adjustment.chromaKeyColor
        ) <= adjustment.chromaKeyTolerance)
    {
        return vec4(0.0);
    }
    else {
        return currentColor;
    }
#elif (0 == 2) // TransferFunction
    return currentColor;
#else
    return currentColor;
#endif
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 233 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 3 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 234 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 208 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 performAdjustmentNightLayers0(vec4 currentColor,
                                        LayerAdjustment adjustment)
{
#if (0 == 0) // Default, None
    return currentColor;
#elif (0 == 1) // ChromaKey
    if (distance(
        currentColor.rgb,
        adjustment.chromaKeyColor
        ) <= adjustment.chromaKeyTolerance)
    {
        return vec4(0.0);
    }
    else {
        return currentColor;
    }
#elif (0 == 2) // TransferFunction
    return currentColor;
#else
    return currentColor;
#endif
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 233 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 4 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 234 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 208 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

vec4 performAdjustmentWaterMasks0(vec4 currentColor,
                                        LayerAdjustment adjustment)
{
#if (0 == 0) // Default, None
    return currentColor;
#elif (0 == 1) // ChromaKey
    if (distance(
        currentColor.rgb,
        adjustment.chromaKeyColor
        ) <= adjustment.chromaKeyTolerance)
    {
        return vec4(0.0);
    }
    else {
        return currentColor;
    }
#elif (0 == 2) // TransferFunction
    return currentColor;
#else
    return currentColor;
#endif
}

//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 233 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Terminated loop over layerGroups
; // preprocessor add semicolon to isolate error messages
#line 234 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

float calculateUntransformedHeight(vec2 uv, vec3 levelWeights,
                                   Layer HeightLayers[NUMLAYERS_HEIGHTMAP])
{

    float height = 0;

    // The shader compiler will remove unused code when variables are multiplied by
    // a constant 0
#if !HEIGHTMAP_BLENDING_ENABLED
    levelWeights = DefaultLevelWeights;
#endif // HEIGHTMAP_BLENDING_ENABLED
    
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 248 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    {
        vec4 colorSample = getSampleHeightLayers0(uv, levelWeights, HeightLayers);
        colorSample = performAdjustmentHeightLayers0(colorSample, HeightLayers[0].adjustment);
        height = colorSample.r;

        height = performLayerSettings(height, HeightLayers[0].settings);
    }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 256 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    return height;
}

float calculateHeight(vec2 uv, vec3 levelWeights, Layer HeightLayers[NUMLAYERS_HEIGHTMAP])
{
    float height = 0;

    // The shader compiler will remove unused code when variables are multiplied by
    // a constant 0
#if !HEIGHTMAP_BLENDING_ENABLED
    levelWeights = DefaultLevelWeights;
#endif // HEIGHTMAP_BLENDING_ENABLED

    
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 271 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    {
        vec4 colorSample = getSampleHeightLayers0(uv, levelWeights, HeightLayers);
        colorSample = performAdjustmentHeightLayers0(colorSample, HeightLayers[0].adjustment);
        float untransformedHeight = colorSample.r;

        TileDepthTransform transform = HeightLayers[0].depthTransform;
        float heightSample =
            transform.depthScale * untransformedHeight + transform.depthOffset;
        if (heightSample > -100000) {
            heightSample = performLayerSettings(heightSample, HeightLayers[0].settings);
            height = heightSample;
        }
    }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 285 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    return height;
}

vec4 calculateColor(vec4 currentColor, vec2 uv, vec3 levelWeights,
                    Layer ColorLayers[NUMLAYERS_COLORTEXTURE])
{
    vec4 color = currentColor;

    // The shader compiler will remove unused code when variables are multiplied by
    // a constant 0
#if !COLORTEXTURE_BLENDING_ENABLED
    levelWeights = DefaultLevelWeights;
#endif // COLORTEXTURE_BLENDING_ENABLED

//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 300 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    {
        vec4 colorSample = getSampleColorLayers0(uv, levelWeights, ColorLayers);
        colorSample = performAdjustmentColorLayers0(colorSample, ColorLayers[0].adjustment);
        colorSample = performLayerSettings(colorSample, ColorLayers[0].settings);

        color = blendColorLayers0(color, colorSample, 1.0);
    }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 308 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

    return color;
}

float gridDots(vec2 uv, vec2 gridResolution) {
    vec2 uvVertexSpace = fract((gridResolution) * uv) + 0.5;

    vec2 uvDotSpace = abs(2.0 * (uvVertexSpace - 0.5));
    return 1.0 - length(1.0 - uvDotSpace);
}

vec4 calculateDebugColor(vec2 uv, vec4 fragPos, vec2 vertexResolution) {
    vec2 uvVertexSpace = fract(vertexResolution * uv);
    vec3 colorUv = vec3(0.3 * uv.x, 0.3 * uv.y, 0);
    vec3 colorDistance = vec3(0.0, 0.0, min(0.4 * log(fragPos.w) - 3.9, 1));
    vec3 colorVertex = (1.0 - length(uvVertexSpace)) * vec3(0.5);
    vec3 colorSum = colorUv + colorDistance + colorVertex;
    return vec4(0.5 * colorSum, 1);
}

float tileResolution(vec2 tileUV, ChunkTile chunkTile) {
    PixelPadding padding;
    padding.startOffset = ivec2(0);
    padding.sizeDifference = ivec2(0);

    vec2 heightResolution = textureSize(chunkTile.textureSampler, 0);
    vec2 uv = tileUVToTextureSamplePosition(chunkTile, tileUV, padding);
    return gridDots(uv, heightResolution);
}

vec4 calculateNight(vec4 currentColor, vec2 uv, vec3 levelWeights,
                    Layer NightLayers[NUMLAYERS_NIGHTTEXTURE],
                    vec3 ellipsoidNormalCameraSpace,
                    vec3 lightDirectionCameraSpace)
{
    vec4 nightColor = vec4(0.0);
    vec4 color = currentColor;

    // The shader compiler will remove unused code when variables are multiplied by
    // a constant 0
#if !NIGHTTEXTURE_BLENDING_ENABLED
    levelWeights = DefaultLevelWeights;
#endif // NIGHTTEXTURE_BLENDING_ENABLED

    vec3 n = normalize(ellipsoidNormalCameraSpace);
    vec3 l = lightDirectionCameraSpace;
    float cosineFactor = clamp(dot(l, normalize(n + 0.20 * l)) * 3 , 0, 1);
    
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 357 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    {
        vec4 colorSample = getSampleNightLayers0(uv, levelWeights, NightLayers);
        colorSample = performAdjustmentNightLayers0(colorSample, NightLayers[0].adjustment);
        colorSample = performLayerSettings(colorSample, NightLayers[0].settings);

        float adjustedAlpha = cosineFactor * colorSample.a;
        // Filter to night side
        vec4 newColor = vec4(cosineFactor * colorSample.xyz, adjustedAlpha);

        color = blendNightLayers0(color, newColor, adjustedAlpha);
    }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 369 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

    return color;
}

vec4 calculateShadedColor(vec4 currentColor, vec3 ellipsoidNormalCameraSpace,
                          vec3 lightDirectionCameraSpace, vec3 viewDirectionCameraSpace,
                          float roughness)
{
    vec3 shadedColor = currentColor.rgb * 0.05;

    vec3 n = normalize(ellipsoidNormalCameraSpace);

    float power = orenNayarDiffuse(
        -lightDirectionCameraSpace,
        viewDirectionCameraSpace,
        ellipsoidNormalCameraSpace,
        roughness);

    vec3 l = lightDirectionCameraSpace;
    power = max(smoothstep(0.0f, 0.1f, max(dot(-l, n), 0.0f)) * power, 0.0f);

    vec4 color = vec4(shadedColor + currentColor.rgb * power, currentColor.a);
    return color;
}

vec4 calculateOverlay(vec4 currentColor, vec2 uv, vec3 levelWeights,
                      Layer Overlays[NUMLAYERS_OVERLAY])
{
    vec4 color = currentColor;

    // The shader compiler will remove unused code when variables are multiplied by
    // a constant 0
#if !OVERLAY_BLENDING_ENABLED
    levelWeights = DefaultLevelWeights;
#endif // OVERLAY_BLENDING_ENABLED

//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 406 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    {
        vec4 colorSample = getSampleOverlays0(uv, levelWeights, Overlays);
        colorSample = performAdjustmentOverlays0(colorSample, Overlays[0].adjustment);

        colorSample = performLayerSettings(colorSample, Overlays[0].settings);

        color = blendNormal(color, colorSample);
        color = blendOverlays0(color, colorSample, 1.0);
    }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 416 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

    return color;
}

vec4 calculateWater(vec4 currentColor, vec2 uv, vec3 levelWeights,
                    Layer WaterMasks[NUMLAYERS_WATERMASK],
                    vec3 ellipsoidNormalCameraSpace,
                    vec3 lightDirectionCameraSpace, vec3 positionCameraSpace,
                    out float reflectance)
{
    vec4 waterColor = vec4(0.0);

    // The shader compiler will remove unused code when variables are multiplied by
    // a constant 0
#if !WATERMASK_BLENDING_ENABLED
    levelWeights = DefaultLevelWeights;
#endif // WATERMASK_BLENDING_ENABLED

//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 435 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    {
        vec4 colorSample = getSampleWaterMasks0(uv, levelWeights, WaterMasks);
        colorSample = performAdjustmentWaterMasks0(colorSample, WaterMasks[0].adjustment);

        colorSample.a = performLayerSettings(colorSample.a, WaterMasks[0].settings);

        waterColor = blendWaterMasks0(waterColor, colorSample, 1.0);
    }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 444 4 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl

    vec3 directionToFragmentCameraSpace = normalize(positionCameraSpace - vec3(0, 0, 0));
    vec3 reflectionDirectionCameraSpace = reflect(lightDirectionCameraSpace, ellipsoidNormalCameraSpace);
    float cosineFactor = clamp(dot(-reflectionDirectionCameraSpace, directionToFragmentCameraSpace), 0, 1);
    cosineFactor = pow(cosineFactor, 100);

    const vec3 specularColor = vec3(1.0);
    const float specularIntensity = 0.4;

    vec3 specularTotal = specularColor * cosineFactor * specularIntensity * waterColor.a;

    reflectance = waterColor.a;
    //return blendNormal(currentColor, waterColor);
    //return currentColor + vec4(specularTotal, 1);
    return currentColor;
}

#endif // TEXTURETILEMAPPING_HGLSL
; // preprocessor add semicolon to isolate error messages
#line 30 0 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\localrenderer_vs.glsl
; // preprocessor add semicolon to isolate error messages
#line 1 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tileheight.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef TILE_HEIGHT_HGLSL
#define TILE_HEIGHT_HGLSL

; // preprocessor add semicolon to isolate error messages
#line 1 1 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScaling_vs.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef POWERSCALING_VS_H_HGLSL
#define POWERSCALING_VS_H_HGLSL

uniform vec4 campos;
uniform mat4 camrot;
uniform vec2 scaling;
uniform vec4 objpos;

; // preprocessor add semicolon to isolate error messages
#line 1 2 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScalingMath.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef POWERSCALING_MATH_HGLSL
#define POWERSCALING_MATH_HGLSL


const float k = 10.0;
const float FLT_MAX = 1e38; // Not max but large enough for the purpose

float log10(float x) {
    return log(x) / log(10.0);
}

vec4 psc_normalization(vec4 v) {
    vec4 v2 = v;
    float l = length(v.xyz);
    v2.xyz = v.xyz / l;
    v2.w = v.w - log10(1.0/l);
    return v2;
}

vec4 psc_addition(vec4 v1, vec4 v2) {
    float ds = v2.w - v1.w;
    if(ds >= 0) {
        float p = pow(k,-ds);
        return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w);
    } else {
        float p = pow(k,ds);
        return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w);
    }
}

vec4 psc_subtraction(vec4 v1, vec4 v2) {
    vec4 negV2 = vec4(-v2.xyz, v2.w);
    return psc_addition(v1, negV2);
}

vec2 psc_addition(vec2 v1, vec2 v2) {
    float ds = v2.y - v1.y;
    if(ds >= 0) {
        float p = pow(k,-ds);
        return vec2(v1.x*p + v2.x, v2.y);
    } else {
        float p = pow(k,ds);
        return vec2(v1.x + v2.x*p, v1.y);
    }
}

vec2 psc_subtraction(vec2 v1, vec2 v2) {
    vec2 negV2 = vec2(-v2.x, v2.y);
    return psc_addition(v1, negV2);
}


vec4 z_normalization(vec4 v_in) {
    vec4 v_out = v_in;
    v_out.z = 0;
    //if ( v_out.z < -v_out.w )
    //  v_out.z = -v_out.w;
    //else if (v_out.z > v_out.w)
    //  v_out.z = v_out.w;
    return v_out;
}

/**
 * Convert a psc vector to a float
 */
vec3 pscToLinear(vec4 position) {
    return pow(k, position.w) * position.xyz;
}

/**
 * Convert a psc scalar to a float
 */
float pscToLinear(vec2 position) {
    return pow(k, position.y) * position.x;
}

#endif
; // preprocessor add semicolon to isolate error messages
#line 34 1 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScaling_vs.hglsl

vec4 psc_to_meter(vec4 v1, vec2 v2) {
    float factor = v2.x * pow(k,v2.y + v1.w);
    return vec4(v1.xyz * factor, 1.0);
}

vec4 psc_scaling(vec4 v1, vec2 v2) {
    float ds = v2.y - v1.w;
    if(ds >= 0) {
        return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y);
    } else {
        return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w);
    }
}

// vertexPosition is returned as the transformed vertex in OS Camera Rig Space in PSC
vec4 pscTransform(inout vec4 vertexPosition, mat4 modelTransform) {
    vec3 local_vertex_pos = mat3(modelTransform) * vertexPosition.xyz;
    
    // PSC addition; local vertex position and the object power scaled world position
    vertexPosition = psc_addition(vec4(local_vertex_pos,vertexPosition.w),objpos);
    
    // PSC addition; rotated and viewscaled vertex and the cameras negative position
    vertexPosition = psc_addition(vertexPosition,vec4(-campos.xyz,campos.w));
    
    // rotate the camera
    vertexPosition.xyz =  mat3(camrot) * vertexPosition.xyz;
    vec4 tmp = vertexPosition;
    vertexPosition = psc_scaling(vertexPosition, scaling);
    
    // project using the rescaled coordinates,
    tmp = psc_to_meter(tmp, scaling);
    
    // Return the vertex tranformed to OS Camera Rig Space
    // in meters.
    return tmp;
}

#endif
; // preprocessor add semicolon to isolate error messages
#line 29 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tileheight.hglsl

; // preprocessor add semicolon to isolate error messages
#line 1 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tile.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef TEXTURETILE_HGLSL
#define TEXTURETILE_HGLSL

struct TileDepthTransform {
    float depthScale;
    float depthOffset;
};

struct TileUvTransform {
    vec2 uvOffset;
    vec2 uvScale;
};

struct ChunkTile {
    sampler2D textureSampler;
    TileUvTransform uvTransform;
};

struct PixelPadding {
    ivec2 startOffset;
    ivec2 sizeDifference;
};

struct ChunkTilePile {
    ChunkTile chunkTile0;
    ChunkTile chunkTile1;
    ChunkTile chunkTile2;
};

struct LayerSettings {
    float opacity;
    float gamma;
    float multiplier;
    float offset;
    float valueBlending;
};

struct LayerAdjustment {
    vec3 chromaKeyColor;
    float chromaKeyTolerance;
};

struct Layer {
    ChunkTilePile pile;
    TileDepthTransform depthTransform;
    LayerSettings settings;
    LayerAdjustment adjustment;
    PixelPadding padding;
    
    // Other layer type properties stuff
    vec3 color;
};

#endif // TEXTURETILE_HGLSL
; // preprocessor add semicolon to isolate error messages
#line 31 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tileheight.hglsl

#ifndef USE_HEIGHTMAP
#define USE_HEIGHTMAP 0
#endif //USE_HEIGHTMAP

#ifndef USE_ACCURATE_NORMALS
#define USE_ACCURATE_NORMALS 0
#endif //USE_ACCURATE_NORMALS

#if USE_HEIGHTMAP
uniform Layer HeightLayers[NUMLAYERS_HEIGHTMAP];
uniform float heightScale;
#endif // USE_HEIGHTMAP

#if USE_ACCURATE_NORMALS && USE_HEIGHTMAP
uniform float deltaTheta0;
uniform float deltaTheta1;
uniform float deltaPhi0;
uniform float deltaPhi1;
uniform float tileDelta;
#endif //USE_ACCURATE_NORMALS && USE_HEIGHTMAP

float getUntransformedTileHeight(vec2 uv, vec3 levelWeights) {
    float height = CHUNK_DEFAULT_HEIGHT;

#if USE_HEIGHTMAP
    // Calculate desired level based on distance to the vertex on the ellipsoid
    // Before any heightmapping is done
    height = calculateUntransformedHeight(
        uv,
        levelWeights, // Variable to determine which texture to sample from
        HeightLayers  // Three textures to sample from
    );
#endif // USE_HEIGHTMAP

    return height;
}

float getTileHeight(vec2 uv, vec3 levelWeights) {
    float height = CHUNK_DEFAULT_HEIGHT;

#if USE_HEIGHTMAP
    // Calculate desired level based on distance to the vertex on the ellipsoid
    // Before any heightmapping is done
    height = calculateHeight(
        uv,
        levelWeights, // Variable to determine which texture to sample from
        HeightLayers  // Three textures to sample from
    );
#endif // USE_HEIGHTMAP

    return height;
}

float getTileHeightScaled(vec2 uv, vec3 levelWeights) {
    float height = getTileHeight(uv, levelWeights);
    
#if USE_HEIGHTMAP
    height *= heightScale;
#endif // USE_HEIGHTMAP

    return height;
}

vec3 getTileNormal(vec2 uv, vec3 levelWeights, vec3 ellipsoidNormalCameraSpace,
                   vec3 ellipsoidTangentThetaCameraSpace,
                   vec3 ellipsoidTangentPhiCameraSpace)
{
    vec3 normal = ellipsoidNormalCameraSpace;

#if USE_ACCURATE_NORMALS
    float deltaPhi = mix(deltaPhi0, deltaPhi1, uv.x);
    float deltaTheta = mix(deltaTheta0, deltaTheta1, uv.y);

    vec3 deltaPhiVec = ellipsoidTangentPhiCameraSpace * deltaPhi;
    vec3 deltaThetaVec = ellipsoidTangentThetaCameraSpace * deltaTheta;

    float height00 = getTileHeightScaled(uv, levelWeights);
    float height10 = getTileHeightScaled(uv + vec2(tileDelta, 0.0f), levelWeights);
    float height01 = getTileHeightScaled(uv + vec2(0.0f, tileDelta), levelWeights);

    vec3 diffTheta = deltaThetaVec + ellipsoidNormalCameraSpace * (height10 - height00);
    vec3 diffPhi = deltaPhiVec + ellipsoidNormalCameraSpace * (height01 - height00);

    normal = normalize(cross(diffTheta, diffPhi));
#endif // USE_ACCURATE_NORMALS
    return normal;
}

#endif // TILE_HEIGHT_HGLSL
; // preprocessor add semicolon to isolate error messages
#line 31 0 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\localrenderer_vs.glsl
; // preprocessor add semicolon to isolate error messages
#line 1 7 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tilevertexskirt.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef TILE_VERTEX_SKIRT_HGLSL
#define TILE_VERTEX_SKIRT_HGLSL

; // preprocessor add semicolon to isolate error messages
#line 1 1 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScaling_vs.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef POWERSCALING_VS_H_HGLSL
#define POWERSCALING_VS_H_HGLSL

uniform vec4 campos;
uniform mat4 camrot;
uniform vec2 scaling;
uniform vec4 objpos;

; // preprocessor add semicolon to isolate error messages
#line 1 2 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScalingMath.hglsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef POWERSCALING_MATH_HGLSL
#define POWERSCALING_MATH_HGLSL


const float k = 10.0;
const float FLT_MAX = 1e38; // Not max but large enough for the purpose

float log10(float x) {
    return log(x) / log(10.0);
}

vec4 psc_normalization(vec4 v) {
    vec4 v2 = v;
    float l = length(v.xyz);
    v2.xyz = v.xyz / l;
    v2.w = v.w - log10(1.0/l);
    return v2;
}

vec4 psc_addition(vec4 v1, vec4 v2) {
    float ds = v2.w - v1.w;
    if(ds >= 0) {
        float p = pow(k,-ds);
        return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w);
    } else {
        float p = pow(k,ds);
        return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w);
    }
}

vec4 psc_subtraction(vec4 v1, vec4 v2) {
    vec4 negV2 = vec4(-v2.xyz, v2.w);
    return psc_addition(v1, negV2);
}

vec2 psc_addition(vec2 v1, vec2 v2) {
    float ds = v2.y - v1.y;
    if(ds >= 0) {
        float p = pow(k,-ds);
        return vec2(v1.x*p + v2.x, v2.y);
    } else {
        float p = pow(k,ds);
        return vec2(v1.x + v2.x*p, v1.y);
    }
}

vec2 psc_subtraction(vec2 v1, vec2 v2) {
    vec2 negV2 = vec2(-v2.x, v2.y);
    return psc_addition(v1, negV2);
}


vec4 z_normalization(vec4 v_in) {
    vec4 v_out = v_in;
    v_out.z = 0;
    //if ( v_out.z < -v_out.w )
    //  v_out.z = -v_out.w;
    //else if (v_out.z > v_out.w)
    //  v_out.z = v_out.w;
    return v_out;
}

/**
 * Convert a psc vector to a float
 */
vec3 pscToLinear(vec4 position) {
    return pow(k, position.w) * position.xyz;
}

/**
 * Convert a psc scalar to a float
 */
float pscToLinear(vec2 position) {
    return pow(k, position.y) * position.x;
}

#endif
; // preprocessor add semicolon to isolate error messages
#line 34 1 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScaling_vs.hglsl

vec4 psc_to_meter(vec4 v1, vec2 v2) {
    float factor = v2.x * pow(k,v2.y + v1.w);
    return vec4(v1.xyz * factor, 1.0);
}

vec4 psc_scaling(vec4 v1, vec2 v2) {
    float ds = v2.y - v1.w;
    if(ds >= 0) {
        return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y);
    } else {
        return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w);
    }
}

// vertexPosition is returned as the transformed vertex in OS Camera Rig Space in PSC
vec4 pscTransform(inout vec4 vertexPosition, mat4 modelTransform) {
    vec3 local_vertex_pos = mat3(modelTransform) * vertexPosition.xyz;
    
    // PSC addition; local vertex position and the object power scaled world position
    vertexPosition = psc_addition(vec4(local_vertex_pos,vertexPosition.w),objpos);
    
    // PSC addition; rotated and viewscaled vertex and the cameras negative position
    vertexPosition = psc_addition(vertexPosition,vec4(-campos.xyz,campos.w));
    
    // rotate the camera
    vertexPosition.xyz =  mat3(camrot) * vertexPosition.xyz;
    vec4 tmp = vertexPosition;
    vertexPosition = psc_scaling(vertexPosition, scaling);
    
    // project using the rescaled coordinates,
    tmp = psc_to_meter(tmp, scaling);
    
    // Return the vertex tranformed to OS Camera Rig Space
    // in meters.
    return tmp;
}

#endif
; // preprocessor add semicolon to isolate error messages
#line 29 7 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tilevertexskirt.hglsl

uniform int xSegments;
uniform float skirtLength;

bool tileVertexIsSkirtVertex() {
    int vertexIDx = gl_VertexID % (xSegments + 3);
    int vertexIDy = gl_VertexID / (xSegments + 3);
    return vertexIDx == 0 || vertexIDy == 0 ||
        vertexIDx == (xSegments + 2) || vertexIDy == (xSegments + 2);
}

float getTileVertexSkirtLength() {
    return tileVertexIsSkirtVertex() ? skirtLength : 0.0;
}

#endif // TILE_VERTEX_SKIRT_HGLSL
; // preprocessor add semicolon to isolate error messages
#line 32 0 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\localrenderer_vs.glsl

layout(location = 1) in vec2 in_uv;

out vec2 fs_uv;
out vec4 fs_position;
out vec3 ellipsoidNormalCameraSpace;
out vec3 levelWeights;
out vec3 positionCameraSpace;

#if USE_ACCURATE_NORMALS
    out vec3 ellipsoidTangentThetaCameraSpace;
    out vec3 ellipsoidTangentPhiCameraSpace;
#endif // USE_ACCURATE_NORMALS

#if USE_ECLIPSE_SHADOWS
out vec3 positionWorldSpace;
uniform dmat4 inverseViewTransform;
#endif

#if SHADOW_MAPPING_ENABLED
    // ShadowMatrix is the matrix defined by:
    // textureCoordsMatrix * projectionMatrix * combinedViewMatrix * modelMatrix
    // where textureCoordsMatrix is just a scale and bias computation: [-1,1] to [0,1]
    uniform dmat4 shadowMatrix;
    out vec4 shadowCoords;
#endif

uniform mat4 projectionTransform;
// Input points in camera space
uniform vec3 p00;
uniform vec3 p10;
uniform vec3 p01;
uniform vec3 p11;
uniform vec3 patchNormalCameraSpace;
uniform float chunkMinHeight;

uniform float distanceScaleFactor;
uniform int chunkLevel;

vec3 bilinearInterpolation(vec2 uv) {
    vec3 p0 = mix(p00, p10, uv.x);
    vec3 p1 = mix(p01, p11, uv.x);
    return mix(p0, p1, uv.y);
}

vec3 getLevelWeights(float distToVertexOnEllipsoid) {
    float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid;
    float desiredLevel = log2(projectedScaleFactor);
    float levelInterp = chunkLevel - desiredLevel;

    return vec3(
        clamp(1.0 - levelInterp, 0.0, 1.0),
        clamp(levelInterp, 0.0, 1.0) - clamp(levelInterp - 1.0, 0.0, 1.0),
        clamp(levelInterp - 1.0, 0.0, 1.0)
    );
}

void main() {
    // Position in cameraspace
    vec3 p = bilinearInterpolation(in_uv);
    
    // Calculate desired level based on distance to the vertex on the ellipsoid
    // Before any heightmapping is done
    float distToVertexOnEllipsoid = length(p + patchNormalCameraSpace * chunkMinHeight);

    // use level weight for height sampling, and output to fragment shader
    levelWeights = getLevelWeights(distToVertexOnEllipsoid);

    // Get the height value and apply skirts
    float height = getTileHeightScaled(in_uv, levelWeights) - getTileVertexSkirtLength();
    
    // Translate the point along normal
    p += patchNormalCameraSpace * height;

    vec4 positionClippingSpace = projectionTransform * vec4(p, 1);

#if USE_ACCURATE_NORMALS
    // Calculate tangents
    ellipsoidTangentThetaCameraSpace = normalize(p10 - p00);
    ellipsoidTangentPhiCameraSpace = normalize(p01 - p00);
#endif // USE_ACCURATE_NORMALS

    // Write output
    fs_uv = in_uv;
    fs_position = z_normalization(positionClippingSpace);
    gl_Position = fs_position;
    ellipsoidNormalCameraSpace = patchNormalCameraSpace;
    positionCameraSpace = p;

#if USE_ECLIPSE_SHADOWS
    positionWorldSpace = vec3(inverseViewTransform * dvec4(p, 1.0));
#endif

#if SHADOW_MAPPING_ENABLED
    shadowCoords = vec4(shadowMatrix * dvec4(p, 1.0));
#endif
}
